package com.app.lzbank.utils;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.atomic.AtomicInteger;

public class SerialNoGenUtils {
    // 渠道简称
    private static final String CHANNEL_PREFIX = "SZHL";

    // 日期格式化器
    private static final ThreadLocal<DateTimeFormatter> DATE_FORMATTER = ThreadLocal.withInitial(() -> DateTimeFormatter.ofPattern("yyyyMMdd"));
    // 日期时间格式化器
    private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
    // 序列号计数器
    private static final ConcurrentHashMap<LocalDate, AtomicInteger> SERIAL_COUNTER = new ConcurrentHashMap<>();

    /**
     * 生成流水号（渠道简称+日期+序列号）
     *
     * @return 流水号
     */
    public static synchronized String genSerialNoByDate() {
        // 获取当前日期
        LocalDate today = LocalDate.now();

        // 如果日期变化，重置序列号
        SERIAL_COUNTER.putIfAbsent(today, new AtomicInteger(0));

        // 获取当前日期的序列号计数器
        AtomicInteger counter = SERIAL_COUNTER.get(today);

        // 生成流水号
        String serialNumber = CHANNEL_PREFIX + today.format(DATE_FORMATTER.get()) + String.format("%03d", counter.getAndIncrement());
        return serialNumber;
    }

    /**
     * 生成流水号（渠道简称+时间戳+四位随机数）
     *
     * @return 流水号
     */
    public static String genSerialNoByTimestamp() {
        // 获取当前日期时间
        LocalDateTime now = LocalDateTime.now();
        // 格式化日期时间为年月日时分秒
        String dateTime = now.format(DATE_TIME_FORMATTER);
        // 生成四位随机数
        int randomNum = ThreadLocalRandom.current().nextInt(10000);
        // 生成流水号
        String serialNumber = CHANNEL_PREFIX + dateTime + String.format("%04d", randomNum);
        return serialNumber;
    }

    /**
     * 测试方法
     */
    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            System.out.println(genSerialNoByDate());
            System.out.println(genSerialNoByTimestamp());
        }
    }
}